<?php
/**
 * Talents come from diligence, and knowledge is gained by accumulation.
 *
 * @author: 晋<657306123@qq.com>
 */

namespace app\admin\service;

use Xin\Support\Arr;
use Xin\Support\Str;

class MenuService{

	/**
	 * @var \app\Request
	 */
	protected $request;

	/**
	 * @var array
	 */
	protected $menus = [];

	/**
	 * @var array
	 */
	protected $breadcrumb = [];

	/**
	 * MenuService constructor.
	 *
	 * @param array $menus
	 */
	public function __construct(array $menus){
		$this->request = app('request');
		$this->menus = $menus;
	}

	/**
	 * 生成菜单
	 */
	public function generate(){
		$rule = $this->resolveRule();
		$this->tree($rule, $this->menus);

		$this->breadcrumb = array_reverse($this->breadcrumb);
		$this->breadcrumb = Arr::multiUnique($this->breadcrumb, 'name');
		if(!empty($this->breadcrumb)){
			array_pop($this->breadcrumb);
		}
	}

	/**
	 * 树形菜单处理
	 *
	 * @param string $rule
	 * @param array  $menus
	 * @return bool
	 */
	protected function tree($rule, &$menus){
		$isActive = false;
		foreach($menus as &$menu){
			$menu['is_active'] = false;
			if(isset($menu['child']) && $this->tree($rule, $menu['child'])){
				$isActive = true;
				$menu['is_active'] = true;

				$this->breadcrumb[] = [
					'name'  => $menu['name'] ?: $menu['child'][0]['name'],
					'title' => isset($menu['title']) ? $menu['title'] : '',
				];
			}elseif($menu['name'] != ''){
				// 校验参数
				$menuRule = explode("?", $menu['name'], 2);
				if($menuRule[0] == $rule){
					if(!isset($menuRule[1]) || $this->checkQueryParams($menuRule[1])){
						$isActive = true;
						$menu['is_active'] = true;

						$this->breadcrumb[] = [
							'name'  => $menu['name'],
							'title' => isset($menu['title']) ? $menu['title'] : '',
						];
					}
				}
			}
		}
		unset($menu);
		return $isActive;
	}

	/**
	 * 检查参数是否合法
	 *
	 * @param string $queryStr
	 * @return bool
	 */
	protected function checkQueryParams($queryStr){
		parse_str($queryStr, $query);
		foreach($query as $k => $v){
			if($v != $this->request->param($k)){
				return false;
			}
		}
		return true;
	}

	/**
	 * 生成当前访问规则
	 *
	 * @return string
	 */
	protected function resolveRule(){
		$controller = Str::snake($this->request->controller());
		$action = $this->request->action(false);
		return "{$controller}/{$action}";
	}

	/**
	 * @return array
	 */
	public function getMenus(){
		return $this->menus;
	}

	/**
	 * @return array
	 */
	public function getBreadcrumb(){
		return $this->breadcrumb;
	}

}
